using System;
using System.Drawing;
using System.Windows.Forms.Design;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Collections.Specialized;

namespace Camalon.Drawing.Design
{

	public class MenuCommandItem:IDisposable
	{


		private class MenuCommand1:MenuCommand
		{
			public MenuCommand1( EventHandler handler,CommandID command ):base(handler, command)
			{
			}
		}

		MenuCommand1	_cmd;
		MenuCommand		_cmdBak;
		bool			_restore;

		IMenuCommandService _mcs;

		public MenuCommandItem(	CommandID command , IMenuCommandService mcs):this( command, mcs, false)
		{
		}


		public MenuCommandItem(	CommandID command , IMenuCommandService mcs, bool restore)
		{
			if( mcs == null) throw new NullReferenceException( "MenuCommandItem::ctor# requires a valid command service"); 
			_cmd = new MenuCommand1( new EventHandler(this.OnChange),command );
			_mcs = mcs;
			_restore = restore;

		}
		

		#region IDisposable Members

		public void Dispose()
		{
			// TODO:  Add MenuCommandItem.Dispose implementation
			this.Restore();
			Delegate.RemoveAll( this.Change, this.Change );
		}

		#endregion


		public CommandID CommandID	{	get{ return _cmd.CommandID;} }

		
		public bool Checked 
		{	
			get{ return _cmd.Checked;} 
			set{ _cmd.Checked = value;}
		}
		
		public bool Enabled 
		{	
			get{ return _cmd.Enabled;} 
			set{ _cmd.Enabled = value;}
		}

		public bool Supported 
		{	
			get{ return _cmd.Supported;} 
			set{ _cmd.Supported = value;}
		}

		public bool Visible 
		{	
			get{ return _cmd.Visible;} 
			set{ _cmd.Visible = value;}
		}

		public int OleStatus {get{ return _cmd.OleStatus; }}
		
		
		public MenuCommand MenuCommand{		get{ return _cmd;}	}



		private bool CanBackup( MenuCommand cmd )
		{
			if( !_restore ) return false;
			if( _cmdBak == cmd ) return false;
			return !(cmd is MenuCommand1);
		}



		public void Add()
		{
			MenuCommand cmd = _mcs.FindCommand( this.CommandID );
			if( CanBackup( cmd )) _cmdBak = cmd; 

			if( cmd == _cmd ) return;

			if(cmd != null) _mcs.RemoveCommand( cmd );
			_mcs.AddCommand( _cmd );
		}
		
		public void Restore()
		{
			MenuCommand cmd = _mcs.FindCommand( this.CommandID );
			if( cmd!=null) 
			{
				_mcs.RemoveCommand( cmd );
				if( _restore && CanBackup( cmd )) _cmdBak = cmd;;
			}

			if(_cmdBak != null) _mcs.AddCommand( _cmdBak );

		}


		public void Remove( bool removeIfEqual )
		{
			MenuCommand cmd = _mcs.FindCommand( this.CommandID );
			if( removeIfEqual ) { if( cmd == _cmd ) _mcs.RemoveCommand( cmd );}
			else if( cmd != null) _mcs.RemoveCommand( cmd );
		}

		protected internal event EventHandler Change;
		protected virtual void OnChange(object sender, EventArgs e)
		{ if( this.Change != null) this.Change(sender, e);}
	}

	


	public class MenuCommandsHelper:IDisposable
	{


		IMenuCommandService _mcs;
		ArrayList _menuCommands  = new ArrayList();
		bool _restore;

		public MenuCommandsHelper(IMenuCommandService menuCommandService, params CommandID[] commandIds ):this( menuCommandService, true, commandIds)
		{

		}


		public MenuCommandsHelper(IMenuCommandService menuCommandService , bool restore, params CommandID[] commandIds )
		{
			if( menuCommandService == null) return;
			if( commandIds == null ) return;
			_mcs			= menuCommandService;
			_restore		= restore;

			foreach( CommandID id in commandIds)
				_menuCommands.Add( new MenuCommandItem( id, _mcs, _restore ));
		}


		#region IDisposable Members


		public void Dispose()
		{
			lock( _menuCommands.SyncRoot )
				foreach( MenuCommandItem cmd in _menuCommands) { cmd.Dispose();}
			_menuCommands.Clear();
		}


		#endregion
		
		public MenuCommandItem this[CommandID cmdId]
		{
			get
			{ 
				lock( _menuCommands.SyncRoot )
					foreach( MenuCommandItem cmd in _menuCommands)
						if( cmd.CommandID == cmdId) {return cmd; }

				return null;
			}
		}

		public void Restore()
		{
			lock( _menuCommands.SyncRoot )
				foreach( MenuCommandItem cmd in _menuCommands) cmd.Restore();
		}

		public void Add()
		{
			lock( _menuCommands.SyncRoot )
				foreach( MenuCommandItem cmd in _menuCommands) cmd.Add();
		}

		public void Remove(bool forceRemoveInequals )
		{
			lock( _menuCommands.SyncRoot )
				foreach( MenuCommandItem cmd in _menuCommands) cmd.Remove(forceRemoveInequals);
		}


		#region Context Menu
		protected internal void ShowComponentTrayMenu( Point pt )
		{
			if( _mcs != null) _mcs.ShowContextMenu(MenuCommands.ComponentTrayMenu, pt.X, pt.Y);
		}

		protected internal void ShowContainerMenu( Point pt )
		{
			if( _mcs != null) _mcs.ShowContextMenu(MenuCommands.ContainerMenu, pt.X, pt.Y);
		}

		protected internal void ShowSelectionMenu( Point pt )
		{
			if( _mcs != null) _mcs.ShowContextMenu(MenuCommands.SelectionMenu, pt.X, pt.Y);
		}
		protected internal void ShowTraySelectionMenu( Point pt )
		{
			if( _mcs != null) _mcs.ShowContextMenu(MenuCommands.TraySelectionMenu, pt.X, pt.Y);
		}

		#endregion Context Menu


	}




}
